/*
    开始时间：2024/3/4
    内容：对进程信号的硬件异常知识点进行代码测试
    作者：剑痴
    结束时间：2024/3/4
*/
#include <iostream>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <cstddef>
using namespace std;

void handler(int sigo)
{
    // cout<<"进程信号signal :"<<sigo<<"--->除0错误"<<endl;
    cout << "进程信号signal :" << sigo << "--->野指针问题" << endl;
    // exit(1);
}
void printsig(sigset_t* p)
{
    cout<<getpid()<<":";
    for(int i = 1;i < 32;i++)
    {
        int bit= sigismember(p,i);
        if(bit == 1)
        {
             cout<<1;
        }else if(bit == 0)
        {
            cout<<0;
        }else
        {
            cout<<-1;
        }
    }
    cout<<endl;
}
int main()
{
    sigset_t set,oset;   //定义信号集
    //初始化信号集
    sigemptyset(&set);
    sigemptyset(&oset);
    // sigfillset(&set);  //获取当前进程的信号集
    // sigfillset(&oset);

    sigaddset(&set,2); //添加信号
    sigprocmask(SIG_BLOCK,&set,nullptr);  //set中更改当前进程的信号屏蔽字,参数how指示如何更改。将某些信号01000000.....00000000为1的进行阻塞,--》不会达到执行动作
    //sigprocmask(SIG_BLOCK,nullptr,&oset);   //读取进程的当前信号屏蔽字通过oset参数传出。
     sigprocmask(SIG_BLOCK,&set,&oset);   //oset和set都是非空指针,则先将原来的信号屏蔽字备份到oset里,然后根据set和how参数更改信号屏蔽字。
     cout<<"set:";
     printsig(&set);
     cout<<endl;  cout<<"oset:";   
     printsig(&oset);  
     cout<<endl;  
     int cnt = 0;
      while(true)
      {
          sigpending(&oset); //获取当前进程的未决的信号集
          printsig(&oset);  //查看当前进程有哪些信号被阻塞了  
          sleep(1); 
          if(cnt++ > 10) sigprocmask(SIG_UNBLOCK,&set,nullptr); //set中解除我们想阻塞的信号-->信号被递达
      }
    // signal(8,handler);
    // signal(11,handler);
    // int* p = nullptr;
    // *p = 100; //野指针问题
    // p = 0;  //这个不会产生野指针问题
    // int n  = 8 / 0;   //除零错误
     //signal(2, SIG_DFL);    //该信号的动作--》终止进程操作
    // signal(2,SIG_IGN);   //该信号的动作--》忽略该信号
    // #define SIG_DFL ((__sighandler_t)0) /* Default action.  */
    // #define SIG_IGN ((__sighandler_t)1) /* Ignore signal.  */
    // while (true)
    // {
    //     cout<<"我是一个正常的进程，正在执行..."<<" pid:"<<getpid()<<endl;
    //     sleep(1);
    // }
    return 0;
}